#include "stdafx.h"
#include "DX10GraphicsSystem.h"


DX10GraphicsSystem::DX10GraphicsSystem(void)
{
	_pSwapChain = NULL;
	_pd3dDevice = NULL;
	_pRenderTargetView = NULL;
	_systemType = System::Types::Graphics;
	_hwnd = NULL;
	_systemName = L"DirectX 10 Renderer";
}

DX10GraphicsSystem::DX10GraphicsSystem( SettingsMap& settings, HWND hWnd )
{
	_pSwapChain = NULL;
	_pd3dDevice = NULL;
	_pRenderTargetView = NULL;
	_systemType = System::Types::Graphics;
	_hwnd = hWnd;
	_systemName = L"DirectX 10 Renderer";
}

DX10GraphicsSystem::~DX10GraphicsSystem(void)
{
	ReleaseCOM(_pRenderTargetView);
	ReleaseCOM(_pSwapChain);
	ReleaseCOM(_pd3dDevice);
}

PSystemScene DX10GraphicsSystem::CreateScene( SettingsMap& settings )
{
	throw std::exception("The method or operation is not implemented.");
}
// DirectX 10 renderer initialization
Error DX10GraphicsSystem::Initialize()
{
	HRESULT hr = S_OK;

	// Calculate width and height
	RECT rc;
	GetClientRect( _hwnd, &rc );
	
	_width = rc.right - rc.left;
	_height = rc.bottom - rc.top;
	

	// Device types list
	D3D10_DRIVER_TYPE driverTypes[] = 
	{
		D3D10_DRIVER_TYPE_HARDWARE,
		D3D10_DRIVER_TYPE_REFERENCE,
	};
	UINT numDriverTypes = sizeof(driverTypes) / sizeof(driverTypes[0]);

	// Swapchain description struct initialization
	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory( &sd, sizeof(sd) );
	sd.BufferCount = 1;
	sd.BufferDesc.Width = _width;
	sd.BufferDesc.Height = _height;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = _refreshRate;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = _hwnd;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = _isWindowed;
	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

	// Creating a device
	hr = D3D10CreateDeviceAndSwapChain(NULL,D3D10_DRIVER_TYPE_HARDWARE, NULL, 0,
		D3D10_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice);
	if( FAILED(hr) )
		return Error::Init_failed;

	// BackBuffer
	ID3D10Texture2D *pBackBuffer;
	
	hr = _pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID*)&pBackBuffer );
	if( FAILED(hr) )
		return Error::Access_denied;
	// Create TargetView for BackBuffer
	hr = _pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &_pRenderTargetView );
	pBackBuffer->Release();
	if( FAILED(hr) )
		return Error::Init_failed;
	// Connect BackBuffer with Graphic Pipeline
	_pd3dDevice->OMSetRenderTargets( 1, &_pRenderTargetView, NULL );

	// Setting viewport
	D3D10_VIEWPORT vp;
	vp.Width = _width;
	vp.Height = _height;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	_pd3dDevice->RSSetViewports( 1, &vp );

	return Error::Success;
}

System::Type DX10GraphicsSystem::GetType()
{
	return _systemType;
}

wchar_t* DX10GraphicsSystem::GetName()
{
	return _systemName;
}

Error DX10GraphicsSystem::DestroyScene( PSystemScene )
{
	throw std::exception("The method or operation is not implemented.");
}
